/*------------------------------------------------------------------------------*\
**   Copyright 2008 Jonhnny Weslley                                             **
**                                                                              **
**   Licensed under the Apache License, Version 2.0 (the "License");            **
**   you may not use this file except in compliance with the License.           **
**   You may obtain a copy of the License at                                    **
**                                                                              **
**       http://www.apache.org/licenses/LICENSE-2.0                             **
**                                                                              **
**   Unless required by applicable law or agreed to in writing, software        **
**   distributed under the License is distributed on an "AS IS" BASIS,          **
**   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   **
**   See the License for the specific language governing permissions and        **
**   limitations under the License.                                             **
\*------------------------------------------------------------------------------*/

package shibernate.contacts

import org.specs._
import org.specs.runner.ConsoleRunner
import shibernate.singleton.{SearchAgent => sa}
import shibernate.singleton.{SessionManager => sm}
import shibernate.singleton.SearchAgent._
import shibernate.singleton.GenericDAO._

object ContactSpecRunner extends ConsoleRunner(ContactSpecification)
object ContactSpecification extends Specification {

  populateDatabase

  "shibernate query language (dsl) - contacts database" should {
    val city = classOf[City]
    val contact = classOf[Contact]

    "have 4 cities" in {
      city().size must be(4)
    }

    "of which 3 cities have state's name starts with 'P'" in {
      val cities = city("state" like "P%")
      cities.size must be(3)
    }

    "of which 3 cities have name starts with 'Ca' or is 'Teresina'" in {
      val results = city(("name" like "Ca%") or ("id" eql 2))
      results.size must be(3)
    }

    "of which 3 cities have name starts with 'Ca' or is of the state of the Paraiba" in {
      val results = city(("name" like "Ca%") or ("state" like "PB"))
      results.size must be(3)
    }

    "one city have id not between 2 and 4" in {
      val results = city(sa.not("id" between (2, 4)))
      results.size must be(1)
    }

    "have 5 contacts" in {
      contact().size must be(5)
    }

    "of which 2 contacts have address zip code starting with '65'" in {
      val addrWithZipCode65 = contact("address.zipCode" like "65%")
      addrWithZipCode65.size must be(2)
    }

    "one contact has address zip code starting with '65' and has gmail account" in {
      val gmailUsers = contact(("address.zipCode" like "65%") and ("info.emailAddress" like "%@gmail.com"))
      gmailUsers.size must be(1)
    }

    "one contact has brazilian's home phone and has id greater than 4" in {
      val results = contact(("info.homePhoneNumber" like "+55%") and ("id" gt 4))
      results.size must be(1)
    }

    "four contacts have city's name starting with 'Ca' or is from 'Teresina'" in {
      val results = contact(("address.city.name" like "Ca%") or ("address.city.id" eql 2))
      results.size must be(4)
    }

  }

  def populateDatabase = {
    val caxias = City(1, "Caxias", "MA")
    val teresina = City(2, "Teresina", "PI")
    val cg = City(3, "Campina Grande", "PB")
    val jampa = City(4, "Joao Pessoa", "PB")

    val jonhnny = Contact(1, "Jonhnny Weslley")
                        .address("Rua x, 525", "65000-900", cg)
                        .email("jonhnnyweslley@gmail.com")()

    val manel = Contact(2, "manel")
                        .address("Same street", "98079 098", cg)
                        .email("manel@server.com")()

    val joao = Contact(3, "joao")
                        .address("some other street", "15426 879", jampa)
                        .email("joao@server.com.br")
                        .homePhoneNumber("83 8833-0207")()

    val foo = Contact(4, "Foo")
                        .address("Wall Street, 300 A", "65001-900", caxias)
                        .email("foo@mail.com")
                        .homePhoneNumber("+55 99 9980-0987")()

    val bar = Contact(5, "Bar")
                        .address("Same Street, 543", "71200-900", teresina)
                        .email("bar@mail.com")
                        .homePhoneNumber("+55 86 9807-2713")()

    transaction {
      save(caxias)
      save(teresina)
      save(cg)
      save(jampa)

      save(jonhnny)
      save(manel)
      save(joao)
      save(foo)
      save(bar)
    }
  }

}